@codeyam/codeyam-cli 0.1.12 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/analyzer-template/.build-info.json +6 -6
  2. package/analyzer-template/log.txt +3 -3
  3. package/codeyam-cli/src/cli.js +9 -0
  4. package/codeyam-cli/src/cli.js.map +1 -1
  5. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js +51 -0
  6. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js.map +1 -0
  7. package/codeyam-cli/src/commands/editor.js +202 -40
  8. package/codeyam-cli/src/commands/editor.js.map +1 -1
  9. package/codeyam-cli/src/commands/editorIsolateArgs.js +25 -0
  10. package/codeyam-cli/src/commands/editorIsolateArgs.js.map +1 -0
  11. package/codeyam-cli/src/commands/telemetry.js +37 -0
  12. package/codeyam-cli/src/commands/telemetry.js.map +1 -0
  13. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +101 -0
  14. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  15. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +70 -0
  16. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -1
  17. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +58 -4
  18. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -1
  19. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +37 -0
  20. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  21. package/codeyam-cli/src/utils/__tests__/telemetry.test.js +159 -0
  22. package/codeyam-cli/src/utils/__tests__/telemetry.test.js.map +1 -0
  23. package/codeyam-cli/src/utils/editorAudit.js +38 -5
  24. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  25. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +13 -7
  26. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -1
  27. package/codeyam-cli/src/utils/editorEntityHelpers.js +18 -3
  28. package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -1
  29. package/codeyam-cli/src/utils/editorScenarios.js +6 -1
  30. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
  31. package/codeyam-cli/src/utils/telemetry.js +106 -0
  32. package/codeyam-cli/src/utils/telemetry.js.map +1 -0
  33. package/codeyam-cli/src/utils/telemetryMiddleware.js +22 -0
  34. package/codeyam-cli/src/utils/telemetryMiddleware.js.map +1 -0
  35. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +28 -0
  36. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
  37. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DYqG1D_d.js +58 -0
  38. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-DggyRwOr.js +41 -0
  39. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-BOi8kpwd.js → entity._sha.scenarios._scenarioId.dev-D1eikpe1.js} +1 -1
  40. package/codeyam-cli/src/webserver/build/client/assets/globals-DRvOjyO3.css +1 -0
  41. package/codeyam-cli/src/webserver/build/client/assets/{manifest-b3f77062.js → manifest-f4212c17.js} +1 -1
  42. package/codeyam-cli/src/webserver/build/client/assets/{root-D5Zi3U2Z.js → root-F-k2uYj5.js} +15 -15
  43. package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-yTyb36j3.js → analysisRunner-if8kM_1Q.js} +1 -1
  44. package/codeyam-cli/src/webserver/build/server/assets/{index-Cr7d_IsG.js → index-CHymws6l.js} +1 -1
  45. package/codeyam-cli/src/webserver/build/server/assets/{init-M_wqNAfu.js → init-D3HkMDbI.js} +1 -1
  46. package/codeyam-cli/src/webserver/build/server/assets/server-build-DTCzJQiH.js +551 -0
  47. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  48. package/codeyam-cli/src/webserver/build-info.json +5 -5
  49. package/codeyam-cli/src/webserver/editorProxy.js +19 -2
  50. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  51. package/codeyam-cli/src/webserver/server.js +32 -0
  52. package/codeyam-cli/src/webserver/server.js.map +1 -1
  53. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +1 -1
  54. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +1 -1
  55. package/package.json +2 -1
  56. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DmBK1JBK.js +0 -58
  57. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-DBa7T2FK.js +0 -41
  58. package/codeyam-cli/src/webserver/build/client/assets/globals-CGrDAxj0.css +0 -1
  59. package/codeyam-cli/src/webserver/build/server/assets/server-build-_ybRgrlc.js +0 -551
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-03-17T15:17:00.245Z",
3
- "buildTime": 1773760620245,
4
- "gitCommit": "b282daf6fc6409b6a9facc3666589360a160dc1d",
2
+ "buildTimestamp": "2026-03-18T14:58:22.078Z",
3
+ "buildTime": 1773845902078,
4
+ "gitCommit": "4dda2c78ef15ac678fb9a0e8f4d270c514f30f81",
5
5
  "nodeVersion": "v20.20.1",
6
6
  "contentHash": "b046e014847d5b02d10d6795839ccd0d5117627cbd0be413260824610596a63d",
7
- "buildNumber": 1071,
8
- "semanticVersion": "0.1.1071",
9
- "version": "0.1.1071 (2026-03-17T15:17+b046e01)"
7
+ "buildNumber": 1092,
8
+ "semanticVersion": "0.1.1092",
9
+ "version": "0.1.1092 (2026-03-18T14:58+b046e01)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [3/17/2026, 3:17:00 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [3/17/2026, 3:17:00 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [3/18/2026, 2:58:21 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [3/18/2026, 2:58:21 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [3/17/2026, 3:17:00 PM] Merged dependencies into root package.json
6
+ [3/18/2026, 2:58:22 PM] Merged dependencies into root package.json
7
7
 
@@ -27,8 +27,11 @@ import memoryCommand from "./commands/memory.js";
27
27
  import editorCommand from "./commands/editor.js";
28
28
  import setupSimulationsCommand from "./commands/setup-simulations.js";
29
29
  import { syncMocksMiddleware } from "./utils/syncMocksMiddleware.js";
30
+ import { telemetryMiddleware } from "./utils/telemetryMiddleware.js";
31
+ import { captureEvent } from "./utils/telemetry.js";
30
32
  import { getDisplayVersion } from "./utils/versionInfo.js";
31
33
  import { simulationGateMiddleware, buildSimulationEpilogue, } from "./utils/simulationGateMiddleware.js";
34
+ import telemetryCommand from "./commands/telemetry.js";
32
35
  // Install global signal handlers for automatic process cleanup
33
36
  // This ensures all child processes (analyzer, capture, etc.) are cleaned up on:
34
37
  // - Ctrl+C (SIGINT)
@@ -49,11 +52,13 @@ yargs(hideBin(process.argv))
49
52
  .usage('CodeYam local development CLI')
50
53
  .middleware(simulationGateMiddleware)
51
54
  .middleware(syncMocksMiddleware)
55
+ .middleware(telemetryMiddleware)
52
56
  // Core commands (always visible in help)
53
57
  .command(defaultCommand)
54
58
  .command(startCommand)
55
59
  .command(stopCommand)
56
60
  .command(memoryCommand)
61
+ .command(telemetryCommand)
57
62
  // Hidden commands (shown in epilogue when simulations are enabled)
58
63
  .command(withoutDescribe(initCommand))
59
64
  .command(withoutDescribe(updateConfigCommand))
@@ -81,6 +86,10 @@ yargs(hideBin(process.argv))
81
86
  .strict()
82
87
  .parseAsync()
83
88
  .catch((error) => {
89
+ captureEvent('cli_error', {
90
+ command: process.argv[2] ?? 'unknown',
91
+ error_type: error?.constructor?.name ?? 'Error',
92
+ });
84
93
  console.error('CLI Error:', error.message);
85
94
  process.exit(1);
86
95
  });
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tests that `codeyam editor isolate` correctly parses multiple component
3
+ * names whether passed as separate args or a single quoted string.
4
+ *
5
+ * Bug: `codeyam editor isolate A B C` failed because yargs .strict()
6
+ * rejected extra positionals beyond the two declared (step, json).
7
+ * Claude would then try one at a time, wasting time and tokens.
8
+ */
9
+ import { parseIsolateArgs } from "../editorIsolateArgs.js";
10
+ describe('parseIsolateArgs', () => {
11
+ it('should parse a single component name from json arg', () => {
12
+ expect(parseIsolateArgs('LogoMark', [])).toEqual(['LogoMark']);
13
+ });
14
+ it('should parse space-separated names from a single quoted json arg', () => {
15
+ // codeyam editor isolate "LogoMark AppHeader Button"
16
+ expect(parseIsolateArgs('LogoMark AppHeader Button', [])).toEqual([
17
+ 'LogoMark',
18
+ 'AppHeader',
19
+ 'Button',
20
+ ]);
21
+ });
22
+ it('should parse comma-separated names from json arg', () => {
23
+ expect(parseIsolateArgs('LogoMark,AppHeader,Button', [])).toEqual([
24
+ 'LogoMark',
25
+ 'AppHeader',
26
+ 'Button',
27
+ ]);
28
+ });
29
+ it('should collect extra positional args from argv._', () => {
30
+ // codeyam editor isolate LogoMark AppHeader Button
31
+ // yargs: json="LogoMark", argv._=["editor", "AppHeader", "Button"]
32
+ expect(parseIsolateArgs('LogoMark', ['editor', 'AppHeader', 'Button'])).toEqual(['LogoMark', 'AppHeader', 'Button']);
33
+ });
34
+ it('should deduplicate names from json and extras', () => {
35
+ expect(parseIsolateArgs('LogoMark', ['editor', 'LogoMark', 'AppHeader'])).toEqual(['LogoMark', 'AppHeader']);
36
+ });
37
+ it('should filter out empty strings', () => {
38
+ expect(parseIsolateArgs('LogoMark AppHeader', [])).toEqual([
39
+ 'LogoMark',
40
+ 'AppHeader',
41
+ ]);
42
+ });
43
+ it('should return empty array when no names provided', () => {
44
+ expect(parseIsolateArgs(undefined, [])).toEqual([]);
45
+ expect(parseIsolateArgs('', [])).toEqual([]);
46
+ });
47
+ it('should filter out "editor" from argv._', () => {
48
+ expect(parseIsolateArgs(undefined, ['editor', 'LogoMark', 'AppHeader'])).toEqual(['LogoMark', 'AppHeader']);
49
+ });
50
+ });
51
+ //# sourceMappingURL=editor.isolateArgs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.isolateArgs.test.js","sourceRoot":"","sources":["../../../../../src/commands/__tests__/editor.isolateArgs.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,qDAAqD;QACrD,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,UAAU;YACV,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,UAAU;YACV,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,mDAAmD;QACnD,mEAAmE;QACnE,MAAM,CACJ,gBAAgB,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAChE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CACJ,gBAAgB,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAClE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1D,UAAU;YACV,WAAW;SACZ,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CACJ,gBAAgB,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CACjE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -939,13 +939,29 @@ function printStep2(root, feature) {
939
939
  console.log();
940
940
  console.log(chalk.bold('Build the feature:'));
941
941
  }
942
+ else {
943
+ console.log(chalk.bold('Prepare the database for this feature:'));
944
+ checkbox('List existing scenarios: `codeyam editor scenarios`');
945
+ console.log(chalk.dim(' Review existing scenarios to find seed data that best demonstrates the feature.'));
946
+ console.log(chalk.dim(" Don't create throwaway seed data — use what's already been curated."));
947
+ checkbox('Pick the scenario with seed data most relevant to this feature');
948
+ console.log(chalk.dim(" Think: which existing data state best exercises the feature you're building?"));
949
+ console.log(chalk.dim(' A scenario with diverse, realistic data is usually the best starting point.'));
950
+ checkbox('Load that scenario to seed the database and preview it:');
951
+ console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
952
+ console.log(chalk.dim(' This switches the active scenario, runs the seed adapter, and refreshes the preview.'));
953
+ console.log(chalk.dim(' If no existing scenario fits, use the default seed: npm run db:seed'));
954
+ console.log();
955
+ }
942
956
  console.log(chalk.bold('Checklist:'));
943
957
  checkbox('Create API routes that read from the database via Prisma');
944
- checkbox('Seed the database with demo data');
945
- checkbox('Create `.codeyam/seed-adapter.ts` so CodeYam can seed the database for scenarios');
946
- console.log(chalk.dim(' The seed adapter reads a JSON file (path passed as CLI arg), wipes tables, inserts rows.'));
947
- console.log(chalk.dim(" Use the project's own ORM (Prisma, Drizzle, etc.). See template for example."));
948
- console.log(chalk.dim(' Run with: npx tsx .codeyam/seed-adapter.ts <path-to-seed-data.json>'));
958
+ if (!projectExists) {
959
+ checkbox('Seed the database with demo data');
960
+ checkbox('Create `.codeyam/seed-adapter.ts` so CodeYam can seed the database for scenarios');
961
+ console.log(chalk.dim(' The seed adapter reads a JSON file (path passed as CLI arg), wipes tables, inserts rows.'));
962
+ console.log(chalk.dim(" Use the project's own ORM (Prisma, Drizzle, etc.). See template for example."));
963
+ console.log(chalk.dim(' Run with: npx tsx .codeyam/seed-adapter.ts <path-to-seed-data.json>'));
964
+ }
949
965
  checkbox('Verify the dev server shows the changes');
950
966
  checkbox('If the feature involves auth, email, payments, or other common patterns: read FEATURE_PATTERNS.md');
951
967
  // Responsive design guidance when building a mobile-responsive web app
@@ -1428,8 +1444,6 @@ function printStep12(root, feature) {
1428
1444
  }
1429
1445
  // ─── Step 13: Present ─────────────────────────────────────────────────
1430
1446
  function printStep13(root, feature) {
1431
- const port = getServerPort();
1432
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1433
1447
  const prevState = readState(root);
1434
1448
  const isResuming = prevState?.step === 13;
1435
1449
  const now = new Date().toISOString();
@@ -1448,18 +1462,9 @@ function printStep13(root, feature) {
1448
1462
  console.log('Present the results to the user and get their approval.');
1449
1463
  console.log();
1450
1464
  console.log(chalk.bold('Checklist:'));
1451
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1452
- console.log(chalk.dim(' Each scenario has a `changeStatus` field: "new", "edited", "impacted", or null.'));
1453
- checkbox('Pick the best scenario to showcase from this working session:');
1454
- console.log(chalk.dim(' Prefer scenarios with changeStatus "new" or "edited" (directly changed in this session).'));
1455
- console.log(chalk.dim(' For app-level scenarios, prefer those showing the new/changed functionality.'));
1456
- console.log(chalk.dim(' NEVER pick a scenario with changeStatus null — those are unchanged from a previous commit.'));
1457
- checkbox('Switch the preview to that scenario using its `id` and `dimension`:');
1458
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1459
- console.log(chalk.dim(' Use the dimension that matches the scenario — check its registered dimensions.'));
1460
- printDimensionGuidance(dim, dimNames);
1461
1465
  checkbox(`Show the results panel: \`codeyam editor show-results\``);
1462
1466
  console.log(chalk.dim(' This opens a visual panel below the terminal showing all scenarios with screenshots.'));
1467
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1463
1468
  console.log(chalk.dim(' The user can click scenarios to switch the live preview.'));
1464
1469
  checkbox('Write a 1-2 sentence summary of what was built');
1465
1470
  checkbox('Report test count and audit status (one line)');
@@ -1689,7 +1694,6 @@ function printMigrateStep4(root) {
1689
1694
  }
1690
1695
  const { pageName, pageIndex, totalPages } = pageInfo;
1691
1696
  writeMigrationStepState(root, 4, pageName, pageIndex, totalPages);
1692
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1693
1697
  console.log();
1694
1698
  console.log(chalk.bold.cyan(`━━━ Migration Step 4: Preview — ${pageName} (${pageIndex + 1}/${totalPages}) ━━━`));
1695
1699
  console.log();
@@ -1699,11 +1703,8 @@ function printMigrateStep4(root) {
1699
1703
  checkbox('Review all scenario screenshots for this page — do they look correct?');
1700
1704
  checkbox('Check for client errors: `codeyam editor client-errors`');
1701
1705
  checkbox('If any issues: fix the scenario data, re-register affected scenarios');
1702
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1703
- checkbox('Pick the best scenario to showcase:');
1704
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1705
- printDimensionGuidance(dim, dimNames);
1706
1706
  checkbox('Show results: `codeyam editor show-results`');
1707
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1707
1708
  console.log();
1708
1709
  console.log(chalk.dim('The user should now see their existing page with live screenshots in the preview.'));
1709
1710
  migrationStopGate(4, pageName, pageIndex, totalPages);
@@ -1863,18 +1864,14 @@ function printMigrateStep10(root) {
1863
1864
  }
1864
1865
  const { pageName, pageIndex, totalPages } = pageInfo;
1865
1866
  writeMigrationStepState(root, 10, pageName, pageIndex, totalPages);
1866
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1867
1867
  console.log();
1868
1868
  console.log(chalk.bold.cyan(`━━━ Migration Step 10: Present — ${pageName} (${pageIndex + 1}/${totalPages}) ━━━`));
1869
1869
  console.log();
1870
1870
  console.log("Show results and commit this page's migration.");
1871
1871
  console.log();
1872
1872
  console.log(chalk.bold('Checklist:'));
1873
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1874
- checkbox('Pick the best scenario to showcase:');
1875
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1876
- printDimensionGuidance(dim, dimNames);
1877
1873
  checkbox('Show results: `codeyam editor show-results`');
1874
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1878
1875
  checkbox('Write a 1-2 sentence summary of what was migrated');
1879
1876
  console.log();
1880
1877
  console.log(chalk.bold('Present a selection menu (AskUserQuestion with these EXACT option labels):'));
@@ -2347,6 +2344,8 @@ async function handleAnalyzeImports(options = {}) {
2347
2344
  sha: e.sha,
2348
2345
  name: e.name,
2349
2346
  filePath: e.filePath || '',
2347
+ isDefaultExport: e.metadata?.notExported === false &&
2348
+ e.metadata?.namedExport === false,
2350
2349
  })));
2351
2350
  if (backfillResult.updated > 0 && !options.silent) {
2352
2351
  console.log(chalk.green(`Linked ${backfillResult.updated} scenario(s) to their entities.`));
@@ -2955,10 +2954,69 @@ async function checkAuditGate() {
2955
2954
  }
2956
2955
  // Re-check after fix
2957
2956
  const retry = await fetchAuditResult();
2958
- return retry?.summary?.allPassing === true;
2957
+ if (retry?.summary?.allPassing === true)
2958
+ return true;
2959
2959
  }
2960
+ // Print specific failures so Claude knows what to fix without running audit separately
2961
+ printAuditGateFailures(data);
2960
2962
  return false;
2961
2963
  }
2964
+ /**
2965
+ * Print a concise summary of audit failures for the gate block message.
2966
+ * This gives Claude immediate context about what to fix without needing
2967
+ * to run `codeyam editor audit` as a separate step.
2968
+ */
2969
+ function printAuditGateFailures(data) {
2970
+ const s = data.summary;
2971
+ if (!s)
2972
+ return;
2973
+ const issues = [];
2974
+ if (s.componentsMissing > 0)
2975
+ issues.push(`${s.componentsMissing} component(s) missing scenarios`);
2976
+ if (s.componentsWithErrors > 0)
2977
+ issues.push(`${s.componentsWithErrors} component(s) with client errors (browser API or runtime errors in captured scenarios)`);
2978
+ if (s.functionsMissing > 0)
2979
+ issues.push(`${s.functionsMissing} function(s) missing test files`);
2980
+ if (s.functionsFailing > 0)
2981
+ issues.push(`${s.functionsFailing} function(s) with failing tests`);
2982
+ if (s.functionsRunnerError > 0)
2983
+ issues.push(`${s.functionsRunnerError} function(s) with test runner errors (the runner crashed — not a test failure)`);
2984
+ if (s.functionsNameMismatch > 0)
2985
+ issues.push(`${s.functionsNameMismatch} function(s) with test name mismatch`);
2986
+ if (s.missingFromGlossary > 0)
2987
+ issues.push(`${s.missingFromGlossary} file(s) with scenarios not in glossary`);
2988
+ if (s.incompleteEntities > 0)
2989
+ issues.push(`${s.incompleteEntities} entity/entities need import analysis`);
2990
+ if (s.miscategorizedScenarios > 0)
2991
+ issues.push(`${s.miscategorizedScenarios} component(s) using page URLs instead of isolation routes`);
2992
+ if (issues.length > 0) {
2993
+ console.error(chalk.yellow('\nAudit failures:'));
2994
+ for (const issue of issues) {
2995
+ console.error(chalk.yellow(` • ${issue}`));
2996
+ }
2997
+ }
2998
+ // Surface client error details inline — these are the most common cause of
2999
+ // Claude looping because the errors require code fixes, not audit re-runs.
3000
+ if (data.components) {
3001
+ const withErrors = data.components.filter((c) => c.status === 'has_errors' && c.clientErrors?.length > 0);
3002
+ if (withErrors.length > 0) {
3003
+ console.error(chalk.yellow('\nClient errors found:'));
3004
+ for (const c of withErrors) {
3005
+ console.error(chalk.red(` ${c.name}:`));
3006
+ for (const err of c.clientErrors.slice(0, 3)) {
3007
+ console.error(chalk.red(` → ${err}`));
3008
+ }
3009
+ if (c.clientErrors.length > 3) {
3010
+ console.error(chalk.dim(` … and ${c.clientErrors.length - 3} more`));
3011
+ }
3012
+ }
3013
+ console.error(chalk.yellow('\nFix: Fix the code errors above, then re-capture the affected scenarios.'));
3014
+ console.error(chalk.yellow('If errors reference browser APIs (localStorage, sessionStorage, window, document),'));
3015
+ console.error(chalk.yellow('create a universal mock: codeyam detect-universal-mocks'));
3016
+ }
3017
+ }
3018
+ console.error(chalk.dim('\nRun `codeyam editor audit` for full details.\n'));
3019
+ }
2962
3020
  // ─── Audit subcommand ────────────────────────────────────────────────
2963
3021
  /**
2964
3022
  * `codeyam editor audit`
@@ -3027,6 +3085,14 @@ async function handleAudit() {
3027
3085
  if (c.clientErrors.length > 3) {
3028
3086
  console.log(chalk.dim(` … and ${c.clientErrors.length - 3} more`));
3029
3087
  }
3088
+ // Detect browser API errors and provide actionable guidance
3089
+ const browserApiPattern = /\b(localStorage|sessionStorage|window\.|document\.|navigator\.|indexedDB|matchMedia|ResizeObserver|IntersectionObserver|MutationObserver)\b/;
3090
+ const hasBrowserApiErrors = c.clientErrors.some((err) => browserApiPattern.test(err));
3091
+ if (hasBrowserApiErrors) {
3092
+ console.log(chalk.yellow(` ⚠ These errors are caused by browser APIs that don't exist during server-side analysis.`));
3093
+ console.log(chalk.yellow(` Fix: Create a universal mock to stub the missing API. Run: codeyam detect-universal-mocks`));
3094
+ console.log(chalk.yellow(` DO NOT re-run the audit or analyze-imports — the error will persist until a mock is created.`));
3095
+ }
3030
3096
  }
3031
3097
  }
3032
3098
  console.log();
@@ -3041,6 +3107,14 @@ async function handleAudit() {
3041
3107
  case 'ok':
3042
3108
  detail = chalk.dim(` (${f.testFile})`);
3043
3109
  break;
3110
+ case 'runner_error':
3111
+ detail = chalk.red(` — test runner crashed: ${f.testFile}`);
3112
+ if (f.errorMessage) {
3113
+ detail += `\n ${chalk.red(f.errorMessage)}`;
3114
+ detail += `\n ${chalk.yellow('Note: This is NOT a test failure — the test runner itself could not execute.')}`;
3115
+ detail += `\n ${chalk.yellow('Try running the test manually: npx vitest run ' + f.testFile)}`;
3116
+ }
3117
+ break;
3044
3118
  case 'failing':
3045
3119
  detail = chalk.red(` — tests failing: ${f.testFile}`);
3046
3120
  break;
@@ -3077,9 +3151,13 @@ async function handleAudit() {
3077
3151
  }
3078
3152
  if (autoRemediationFailed) {
3079
3153
  console.log(chalk.red(' analyze-imports was run automatically but these entities are STILL incomplete.'));
3080
- console.log(chalk.red(' This usually means the analysis had errorscheck the output above for details.'));
3081
- console.log(chalk.yellow(' Common causes: stale entity references from refactoring, missing source files.'));
3082
- console.log(chalk.yellow(' Try: run `codeyam editor analyze-imports` manually to see the full error output.'));
3154
+ console.log(chalk.red(' DO NOT re-run analyze-imports or the audit in a loop — the result will be the same.'));
3155
+ console.log(chalk.yellow(' This means the analysis failed for these entities. Common causes:'));
3156
+ console.log(chalk.yellow(' Entity code uses browser APIs (localStorage, window, document) create a universal mock'));
3157
+ console.log(chalk.yellow(' • Source file was renamed/deleted but glossary still references the old path'));
3158
+ console.log(chalk.yellow(' • Entity has import errors that prevent analysis'));
3159
+ console.log(chalk.yellow(' To investigate: run `codeyam editor analyze-imports` (without --silent) to see the full error.'));
3160
+ console.log(chalk.yellow(' To fix browser API issues: run `codeyam detect-universal-mocks`'));
3083
3161
  }
3084
3162
  else {
3085
3163
  console.log(chalk.yellow(' Run `codeyam editor analyze-imports` to analyze these entities'));
@@ -3121,6 +3199,9 @@ async function handleAudit() {
3121
3199
  if (summary.functionsFailing > 0) {
3122
3200
  parts.push(`${summary.functionsFailing} function${summary.functionsFailing !== 1 ? 's' : ''} with failing tests`);
3123
3201
  }
3202
+ if (summary.functionsRunnerError > 0) {
3203
+ parts.push(`${summary.functionsRunnerError} function${summary.functionsRunnerError !== 1 ? 's' : ''} with test runner errors (not test failures — see details above)`);
3204
+ }
3124
3205
  if (summary.functionsNameMismatch > 0) {
3125
3206
  parts.push(`${summary.functionsNameMismatch} function${summary.functionsNameMismatch !== 1 ? 's' : ''} with test name mismatch (missing top-level describe)`);
3126
3207
  }
@@ -3267,6 +3348,8 @@ async function handleScenarioCoverage() {
3267
3348
  sha: e.sha,
3268
3349
  name: e.name,
3269
3350
  filePath: e.filePath || '',
3351
+ isDefaultExport: e.metadata?.notExported === false &&
3352
+ e.metadata?.namedExport === false,
3270
3353
  })));
3271
3354
  }
3272
3355
  }
@@ -3812,7 +3895,9 @@ const editorCommand = {
3812
3895
  describe: 'Debug: output directory for the bundle',
3813
3896
  });
3814
3897
  }
3815
- return builder;
3898
+ // Allow extra positional args for subcommands like `isolate A B C`
3899
+ // without yargs rejecting them as unknown.
3900
+ return builder.strict(false);
3816
3901
  },
3817
3902
  handler: async (argv) => {
3818
3903
  const root = getProjectRoot();
@@ -3897,13 +3982,10 @@ const editorCommand = {
3897
3982
  return;
3898
3983
  }
3899
3984
  // Subcommand: codeyam editor isolate "StarRating CategoryBadge DrinkCard"
3985
+ // Also supports: codeyam editor isolate StarRating CategoryBadge DrinkCard
3900
3986
  if (argv.step === 'isolate') {
3901
- const names = [];
3902
- if (argv.json)
3903
- names.push(...argv.json.split(/[\s,]+/).filter(Boolean));
3904
- // Collect any extra positional args (yargs puts them in argv._)
3905
- const extras = argv._.filter((a) => typeof a === 'string' && a !== 'editor');
3906
- names.push(...extras);
3987
+ const { parseIsolateArgs } = await import('./editorIsolateArgs.js');
3988
+ const names = parseIsolateArgs(argv.json, argv._);
3907
3989
  handleIsolate(names);
3908
3990
  return;
3909
3991
  }
@@ -4091,6 +4173,41 @@ const editorCommand = {
4091
4173
  catch {
4092
4174
  // Non-fatal — migration failure shouldn't block editor startup
4093
4175
  }
4176
+ // Auto-seed on fresh clone: if no scenario has ever been activated
4177
+ // (active-scenario.json doesn't exist), seed the application database
4178
+ // with the first application scenario that has seed data.
4179
+ const activeScenarioPath = path.join(projectRoot, '.codeyam', 'active-scenario.json');
4180
+ if (!fs.existsSync(activeScenarioPath)) {
4181
+ try {
4182
+ const { getDatabase: getDb } = await import('../../../packages/database/index.js');
4183
+ const seedDb = getDb();
4184
+ const appScenario = await seedDb
4185
+ .selectFrom('editor_scenarios')
4186
+ .select(['id', 'name', 'type'])
4187
+ .where('project_id', '=', project.id)
4188
+ .where('type', '=', 'application')
4189
+ .orderBy('created_at', 'asc')
4190
+ .executeTakeFirst();
4191
+ if (appScenario) {
4192
+ const seedFile = path.join(projectRoot, '.codeyam', 'editor-scenarios', `${appScenario.id}.seed.json`);
4193
+ if (fs.existsSync(seedFile)) {
4194
+ const { switchActiveScenario } = await import('../utils/editorScenarioSwitch.js');
4195
+ const seedResult = await switchActiveScenario({
4196
+ scenarioId: appScenario.id,
4197
+ scenarioName: appScenario.name || undefined,
4198
+ scenarioType: appScenario.type || undefined,
4199
+ projectRoot,
4200
+ });
4201
+ if (seedResult.seedResult?.success) {
4202
+ console.log(chalk.green(` Auto-seeded database with scenario: ${appScenario.name || appScenario.id}`));
4203
+ }
4204
+ }
4205
+ }
4206
+ }
4207
+ catch {
4208
+ // Non-fatal — auto-seed is best-effort
4209
+ }
4210
+ }
4094
4211
  // `codeyam editor` (no step) always implies editor mode.
4095
4212
  // The empty-folder heuristic is no longer needed here — running this
4096
4213
  // command IS the signal. We still detect empty folders so that
@@ -4235,6 +4352,48 @@ const editorCommand = {
4235
4352
  }
4236
4353
  }
4237
4354
  }
4355
+ // Backfill page_file_path for application scenarios that have a URL but
4356
+ // no page_file_path. This resolves the file from the URL using Next.js
4357
+ // routing conventions, enabling syncScenarioEntityShas to link them to
4358
+ // entities. Covers fresh clones where JSON files lack pageFilePath.
4359
+ try {
4360
+ const { getDatabase: getDb } = await import('../../../packages/database/index.js');
4361
+ const pfpDb = getDb();
4362
+ const unresolved = await pfpDb
4363
+ .selectFrom('editor_scenarios')
4364
+ .select(['id', 'url'])
4365
+ .where('project_id', '=', project.id)
4366
+ .where('component_name', 'is', null)
4367
+ .where('page_file_path', 'is', null)
4368
+ .where('url', 'is not', null)
4369
+ .execute();
4370
+ if (unresolved.length > 0) {
4371
+ const { scanPageFilePaths: scanPfp } = await import('../utils/entityChangeStatus.server.js');
4372
+ const { matchUrlToPageFile } = await import('../utils/routePatternMatching');
4373
+ const { allFiles: pfpFiles } = scanPfp(projectRoot);
4374
+ let pfpResolved = 0;
4375
+ for (const row of unresolved) {
4376
+ const r = row;
4377
+ if (!r.url)
4378
+ continue;
4379
+ const matched = matchUrlToPageFile(r.url, pfpFiles);
4380
+ if (matched) {
4381
+ await pfpDb
4382
+ .updateTable('editor_scenarios')
4383
+ .set({ page_file_path: matched })
4384
+ .where('id', '=', r.id)
4385
+ .execute();
4386
+ pfpResolved++;
4387
+ }
4388
+ }
4389
+ if (pfpResolved > 0) {
4390
+ console.log(chalk.green(` Resolved page_file_path for ${pfpResolved} scenario(s) from URL`));
4391
+ }
4392
+ }
4393
+ }
4394
+ catch {
4395
+ /* Non-fatal — page_file_path backfill from URL */
4396
+ }
4238
4397
  // Backfill entity_sha on scenarios that were synced before entities existed.
4239
4398
  // This runs independently of analyze-imports so fresh clones and file-synced
4240
4399
  // scenarios get linked to their entities even when auto-analyze doesn't trigger.
@@ -4247,6 +4406,8 @@ const editorCommand = {
4247
4406
  sha: e.sha,
4248
4407
  name: e.name,
4249
4408
  filePath: e.filePath || '',
4409
+ isDefaultExport: e.metadata?.notExported === false &&
4410
+ e.metadata?.namedExport === false,
4250
4411
  })));
4251
4412
  if (result.updated > 0) {
4252
4413
  console.log(chalk.green(` Linked ${result.updated} scenario(s) to their entities`));
@@ -4341,8 +4502,9 @@ const editorCommand = {
4341
4502
  if (step >= 8) {
4342
4503
  const auditOk = await checkAuditGate();
4343
4504
  if (!auditOk) {
4344
- console.error(chalk.red.bold('BLOCKED: The audit has not passed. Run `codeyam editor audit` and fix all issues before proceeding.'));
4345
- console.error(chalk.yellow('Every function and hook must have a test file. Every component must have scenarios.'));
4505
+ // checkAuditGate() already printed specific failure details above
4506
+ console.error(chalk.red.bold('BLOCKED: The audit has not passed. Fix the issues listed above before proceeding.'));
4507
+ console.error(chalk.yellow('DO NOT re-run the audit in a loop — fix the underlying issues first.'));
4346
4508
  process.exit(1);
4347
4509
  }
4348
4510
  }